#ifndef SFASDUPARSER_H
#define SFASDUPARSER_H

#include <QString>
#include <vector>
#include <map>
#include <QMap>
#include "IEC103Type.h"
#include "SF103_Type.h"
using namespace std;

class SFAsduParser
{
public:
    SFAsduParser();
    virtual ~ SFAsduParser();

    int recvPacketTypeFilter(const QByteArray& packet);  // 对接收的报文进行分类过滤, 返回读定值的具体服务类型
    QStringList parseBillInfo(const int replyType, const QByteArray &packet);      // 返回解析的定值有关定值模板数据序列（name，value）

    //在发送第一个命令读全部组的标题后，解析出的全部组的组号和组名信息结果，这个是后续解析对应各组的前提
    QMap<QString, QString> m_groupNoNameMap;      // 全部标题和组号信息,组号是唯一的作为map的key保证多次读取也不重复

    QMap<QString, BillTableStruct> getBillTableMap(){ return m_billTablesMap;}

    void clearBillTableBuffer();

private:
    void splitApciAsdu(QByteArray &packet, QByteArray &apci, QByteArray &asdu);
    bool parseRecvPacket(const QByteArray &pData, int dataLen);

    /*
     * @Desc: 处理接收到的可变帧长度报文
     * @Param: pData　解析数据开始地址
     * @Param: dataLen　解析数据长度
     * @Return: 解析成功或失败
     */
    bool parseVariableData(const QByteArray &pData);

    /*
     * @Desc: 处理ASDU10 报文，包括设备回的读定值值描述等可变帧长报文
     * @Para: 报文，报文长度
     * @Return: 解析成功或者失败
     */
    virtual void parseASDU10(const QByteArray& packet);

    QString sendPacket(); // 给tcp 服务端提供报文

    //显示虽有的数据集的value,初始化定值模板各项列表
    void showDataSets(vector<SF_OneDataSetItemStruct> &dataSets);

    // 通过指定组的中文名来查询组号
    QString findGroupNoByGroupName(const QString &groupName, vector<SF_OneDataSetItemStruct> &dataSets);

    /*
     * @Desc: 处理接收大的可变帧长报文
     * @Param: 报文数据
     * @Return： 解析成功或者失败
     */
public:
    vector<SF_OneDataSetItemStruct> parseASDU10AllValue(const QByteArray &packet);
    QStringList parseBillTitles(const QByteArray &packet);     // 同时返回组号和标题
    QStringList parseBillArea(const QByteArray &packet);
    QStringList parseBillValueNames(const QByteArray &packet);
    QStringList parseBillValueUnits(const QByteArray &packet);
    QStringList parseBillDimension(const QByteArray &packet);
    QStringList parseBillDefaultValue(const QByteArray &packet);
    QStringList parseBillRealValue(const QByteArray &packet);
    QStringList parseBillUnkown(const QByteArray& packet);
    QStringList parseBillValueDataTypes(const QByteArray &packet);

    void getBillTitleGroupNo(const QByteArray &packet);     // packet 参数是查询全部租标题的回复，将组号和标题一一对应

    // 获取定制值有关的组号
    void getBillRelationGroupNos(QMap<QString, QString> &groupNoAndName);

    QStringList m_billValueName;
    QStringList m_billValueMinList;
    QStringList m_billValueMaxList;
    QStringList m_billValueStepList;
    QStringList m_billValueDefaultList;
    QStringList m_billValueCurrList;
    QStringList m_billValueUinitList;

private:
    QString m_clientAddr = "01";
    QString m_rii = "00";   // 返回信息标志可以固定方便操作

    //由读所有组的标题来初始化这些基础信息
    QString m_ybGroupNo;          // 压板组, 组名包含有关键字“定值”，返回组号16进制字符串
    QStringList m_billValueGroupsNo;   // 全部定值有关组的组号
    QString m_deviceSysGroupNo;      // 系统组

    QList<BillTableStruct> m_billTables;      // 存储解析完的结果，供界面展示的时候使用
    QMap<QString, BillTableStruct> m_billTablesMap;  // 组号 - 组各项值信息，包含全部定值组相关信息
};

#endif
